package com.sz.app.oss.api.logistics.waybill;

import com.sz.app.oss.constants.Permissions;
import com.sz.biz.app.web.BaseController;
import com.sz.biz.logistics.core.dto.ProductGroupDto;
import com.sz.biz.logistics.core.entity.ProductGroup;
import com.sz.biz.logistics.core.service.ProductGroupService;
import com.sz.biz.logistics.serialno.algorithm.AlgorithmFactory;
import com.sz.biz.logistics.serialno.constants.BillNumberConstants;
import com.sz.biz.logistics.serialno.constants.BillNumberMessagesCodes;
import com.sz.biz.logistics.serialno.dto.NoBatchGenerateUserDto;
import com.sz.biz.logistics.serialno.dto.SerialNoGenerateDto;
import com.sz.biz.logistics.serialno.dto.SerialNoRuleDetailDto;
import com.sz.biz.logistics.serialno.service.NoManagementService;
import com.sz.biz.logistics.serialno.service.NoRuleService;
import com.sz.biz.logistics.serialno.service.VerifyRuleService;
import com.sz.common.base.dto.QResultDto;
import com.sz.common.base.dto.QueryParams;
import com.sz.common.base.dto.ResultDto;
import com.sz.common.base.utils.StringUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static com.sz.biz.logistics.serialno.constants.BillNumberConstants.NumberType.WAYBILL_NUMBER;

/**
 * Function: 单号及规则管理控制 <br>
 * Author: Johnboy <br>
 * Date: 2017-12-07 17:28:00
 *
 * @author Johnboy
 */
@RestController
@RequestMapping("/${api}/biz/waybill")
@Api(description = " ", tags = "062、运单号管理")
public class WaybillNoRuleController extends BaseController {

    @Autowired
    private VerifyRuleService verifyRuleService;

    @Autowired
    private NoRuleService waybillNoRuleService;

    @Autowired
    private NoManagementService noManagementService;

    @Autowired
    private ProductGroupService productGroupService;

    @ApiOperation(value = "规则搜索")
    @ApiImplicitParams( {
            @ApiImplicitParam(name = "q", value = "查询的关键字",
                    dataType = "string", paramType = "query") ,
            @ApiImplicitParam(name = "isAsc", value = "排序类型,true为升序，false为降序", required = false,
                    dataType = "boolean", paramType = "query") ,
            @ApiImplicitParam(name = "pageIndex", value = "分页 默认第一页",
                    dataType = "int", paramType = "query") ,
            @ApiImplicitParam(name = "pageSize", value = "页面大小",
                    dataType = "int", paramType = "query") ,
            @ApiImplicitParam(name = "type", value = "规则类型：1：渠道单号，2:运单号",
                    dataType = "int", paramType = "query")
    })
    @RequestMapping(value = "/rules", method = RequestMethod.GET)
    public QResultDto verifyRule(@RequestParam(defaultValue = "") String q ,
                                 @RequestParam(required = false, defaultValue = "true") boolean isAsc ,
                                 @RequestParam(defaultValue = "1") int pageIndex ,
                                 @RequestParam(name = "pageSize", defaultValue = "10") int pageSize) {
        q = StringUtils.replaceSqlPattern(q);
        return verifyRuleService.query(new QueryParams(pageSize , pageIndex , q , "" , isAsc).put("type" ,
                BillNumberConstants.NumberType.WAYBILL_NUMBER));
    }
    
    @RequestMapping(value = "/rules/save", method = RequestMethod.POST)
    @RequiresPermissions(Permissions.BIZ_MGT_BASE_WAYBILL_NUMBER)
    public ResultDto saveRules(@RequestBody SerialNoRuleDetailDto waybillNoDetailDto) {
        waybillNoRuleService.save(waybillNoDetailDto,BillNumberConstants.NumberType.WAYBILL_NUMBER);
        ResultDto resultDto = this.getSaveSuccessDto(BillNumberMessagesCodes.MODULE_RULE);
        return resultDto;
    }

    /**
     * 响应前端更新规则的请求
     * @param serialNoRuleDetailDto 规则详情封装对象
     * @param id 被更新规则的数据库ID
     * @return 更新结果
     */
    @RequestMapping(value = "/rules/update/{id}", method = RequestMethod.POST)
    @RequiresPermissions(Permissions.BIZ_MGT_BASE_WAYBILL_NUMBER)
    public ResultDto updateRules(@RequestBody SerialNoRuleDetailDto serialNoRuleDetailDto, @PathVariable Integer id) {
        serialNoRuleDetailDto.setType(BillNumberConstants.NumberType.WAYBILL_NUMBER);
        waybillNoRuleService.update(serialNoRuleDetailDto,id);
        ResultDto resultDto = this.getUpdateSuccessDto(
                BillNumberMessagesCodes.MODULE_RULE);
        return resultDto;
    }

    /**
     * 响应前端拉取校验位算法列表的请求
     * @return 算法列表
     */
    @RequestMapping(value = "/rules/verify", method = RequestMethod.GET)
    public ResultDto getRules() {
        ResultDto resultDto = new ResultDto();
        resultDto.setData(AlgorithmFactory.getAlgorithmInfoDtos(WAYBILL_NUMBER));
        return resultDto;
    }

    /**
     * 响应前端拉取校验位算法列表的请求
     * @return 算法列表
     */
    @RequestMapping(value = "/rules/ruleList", method = RequestMethod.GET)
    public ResultDto getRuleList() {
        ResultDto resultDto = new ResultDto();
        resultDto.setData(AlgorithmFactory.getAlgorithmInfoDtos(WAYBILL_NUMBER));
        return resultDto;
    }

    @ApiOperation(value = "搜索运单号规则", notes = "搜索运单号列表，支持分页")
    @ApiImplicitParams( {
            @ApiImplicitParam(name = "q", value = "查询的关键字",
                    dataType = "string", paramType = "query") ,
            @ApiImplicitParam(name = "isAsc", value = "排序类型,true为升序，false为降序", required = false,
                    dataType = "boolean", paramType = "query") ,
            @ApiImplicitParam(name = "pageIndex", value = "分页 默认第一页",
                    dataType = "int", paramType = "query") ,
            @ApiImplicitParam(name = "pageSize", value = "页面大小",
                    dataType = "int", paramType = "query") ,
            @ApiImplicitParam(name = "productUid", value = "产品Uid",
                    dataType = "string", paramType = "query") ,
            @ApiImplicitParam(name = "productGroupId", value = "二产品组",
                    dataType = "int", paramType = "query"),
            @ApiImplicitParam(name="refParentGroupId", value = "一级产品组",
                    dataType = "int", paramType="query"),
            @ApiImplicitParam(name = "status", value = "状态 1：全部 2：已启用3：已停用",
                    dataType = "int", paramType = "query")
    })
    @RequestMapping(value = "/rules/search", method = RequestMethod.GET)
    public ResultDto queryRules(@RequestParam(defaultValue = "") String q ,
                                @RequestParam(required = false, defaultValue = "true") boolean isAsc ,
                                @RequestParam(defaultValue = "1") int pageIndex ,
                                @RequestParam(name = "pageSize", defaultValue = "10") int pageSize ,
                                @RequestParam(defaultValue = "") String productUid,
                                @RequestParam(defaultValue = "0") int productGroupId,
                                @RequestParam(defaultValue = "0") int refParentGroupId,
                                @RequestParam(defaultValue = "1")int status) {
        q = StringUtils.replaceSqlPattern(q);
        Map<String,Object> paramMap = new HashMap<>();
        if (! StringUtils.isEmpty(productUid)) {
            paramMap.put("refUid" , productUid);
        }
        List<Integer> refIds = new ArrayList<>();
        if (refParentGroupId > 0) {
            if (productGroupId > 0) {
                refIds.add(productGroupId);
            }
            else {
                List<ProductGroupDto> productGroupDtos = productGroupService.findByParentId(refParentGroupId);
                if (productGroupDtos != null && productGroupDtos.size() > 0) {
                    for(ProductGroup p : productGroupDtos) {
                        refIds.add(p.getId());
                    }
                }
            }
            if (refIds.size() > 0) {
                paramMap.put("refId" , refIds);
            }
        }
        if (status == 2) {
            paramMap.put("status" , status);
        }
        if (status == 3) {
            paramMap.put("status" , status);
        }
        paramMap.put("type",BillNumberConstants.NumberType.WAYBILL_NUMBER);
        return waybillNoRuleService.findRules(new QueryParams(pageSize , pageIndex , q , "" , isAsc).put(paramMap),
                BillNumberConstants.NumberType.WAYBILL_NUMBER);
    }

    @ApiOperation(value = "渠道规则--启用", notes = "启用规则")
    @ApiImplicitParams( {
            @ApiImplicitParam(name = "id", value = "id", dataType = "int", paramType = "path")
    })
    @RequestMapping(value = "/rules/enable/{id}", method = RequestMethod.POST)
    @RequiresPermissions(Permissions.BIZ_MGT_BASE_WAYBILL_NUMBER)
    public ResultDto enableRule(@PathVariable int id) {
        waybillNoRuleService.enableRules(id);
        return this.getOperateSuccessDto(
                BillNumberMessagesCodes.MODULE_WAYBILL_RULE_ENABLE_SUCCESS);
    }

    @ApiOperation(value = "模拟生成出来的单号", notes = "通过id 获取模拟生成的单号")
    @ApiImplicitParams( {
            @ApiImplicitParam(name = "id", value = "id", dataType = "int", paramType = "path")
    })
    @RequestMapping(value = "/rules/example/{id}", method = RequestMethod.GET)
    @RequiresPermissions(Permissions.BIZ_MGT_BASE_WAYBILL_NUMBER)
    public ResultDto getRulesExampleChannelNo(@PathVariable int id) {
        List<String> results = waybillNoRuleService.getExampleChannelNos(id);
        ResultDto resultDto = new ResultDto();
        resultDto.setData(results);
        return resultDto;
    }

    @ApiOperation(value = "运单号规则详细信息", notes = "运单号规则详细信息")
    @ApiImplicitParams( {
            @ApiImplicitParam(name = "id", value = "id", dataType = "int", paramType = "path")
    })
    @RequestMapping(value = "/rules/{id}", method = RequestMethod.GET)
    public ResultDto queryRuleById(@PathVariable int id) {
        SerialNoRuleDetailDto serialNoRuleDetailDto = waybillNoRuleService.queryDetailsDtoById(id);
        ResultDto resultDto = new ResultDto();
        resultDto.setData(serialNoRuleDetailDto);
        return resultDto;
    }

    @ApiOperation(value = "运规则--停用", notes = "停用规则")
    @ApiImplicitParams( {
            @ApiImplicitParam(name = "id", value = "id", dataType = "int", paramType = "path")
    })
    @RequestMapping(value = "/rules/disable/{id}", method = RequestMethod.POST)
    @RequiresPermissions(Permissions.BIZ_MGT_BASE_WAYBILL_NUMBER)
    public ResultDto disableRule(@PathVariable int id) {
        waybillNoRuleService.disableRules(id);
        return this.getOperateSuccessDto(
                BillNumberMessagesCodes.MODULE_WAYBILL_RULE_DISABLE_SUCCESS);
    }

    @ApiOperation(value = "运单号--手动生成单号", notes = "渠道单号--手动生成单号")
    @RequestMapping(value = "/waybillno/generate", method = RequestMethod.POST)
    @RequiresPermissions(Permissions.BIZ_MGT_BASE_WAYBILL_NUMBER)
    public ResultDto generateChannelNo(@RequestBody SerialNoGenerateDto serialNoGenerateDto) {
            long numbers = waybillNoRuleService.generateChannelNo(serialNoGenerateDto,BillNumberConstants.NumberType
                .WAYBILL_NUMBER);
        return new ResultDto(numbers);
    }

    @ApiOperation(value = "获取产品组规则下面的指定的产品",notes = "通过产品组获取产品组下指定的产品")
    @ApiImplicitParams( {
            @ApiImplicitParam(name = "q", value = "查询的关键字",
                    dataType = "string", paramType = "query") ,
            @ApiImplicitParam(name = "isAsc", value = "排序类型,true为升序，false为降序", required = false,
                    dataType = "boolean", paramType = "query") ,
            @ApiImplicitParam(name = "pageIndex", value = "分页 默认第一页",
                    dataType = "int", paramType = "query") ,
            @ApiImplicitParam(name = "pageSize", value = "页面大小",
                    dataType = "int", paramType = "query"),
            @ApiImplicitParam(name="productGroupId", value = "二级产品组",
                    dataType = "int", paramType="query")})
    @RequestMapping(value = "/waybillno/product/search",method = RequestMethod.GET)
    public QResultDto productSearch(@RequestParam(defaultValue = "") String q ,
                                    @RequestParam(required = false, defaultValue = "true") boolean isAsc ,
                                    @RequestParam(defaultValue = "1") int pageIndex ,
                                    @RequestParam(name = "pageSize", defaultValue = "10") int pageSize,
                                    @RequestParam(defaultValue = "0") int productGroupId){
        Map<String,Object> paramData = new HashMap<>();
        if(productGroupId>0){
            paramData.put("refId",productGroupId);
        }
        QResultDto resultDto = waybillNoRuleService.findProductByQueryParams(new QueryParams(pageSize , pageIndex , q , "" ,
                isAsc).put(paramData));
        return resultDto;
    }


    @ApiOperation(value = "搜索运单号批次", notes = "搜索运单号批次")
    @ApiImplicitParams( {
            @ApiImplicitParam(name = "q", value = "查询的关键字",
                    dataType = "string", paramType = "query") ,
            @ApiImplicitParam(name = "isAsc", value = "排序类型,true为升序，false为降序", required = false,
                    dataType = "boolean", paramType = "query") ,
            @ApiImplicitParam(name = "pageIndex", value = "分页 默认第一页",
                    dataType = "int", paramType = "query") ,
            @ApiImplicitParam(name = "pageSize", value = "页面大小",
                    dataType = "int", paramType = "query") ,
            @ApiImplicitParam(name = "productUid", value = "产品Uid",
                    dataType = "string", paramType = "query") ,
            @ApiImplicitParam(name = "batchNumber", value = "批次号",
                    dataType = "string", paramType = "query") ,
            @ApiImplicitParam(name = "waybillNumber", value = "渠道单号",
                    dataType = "string", paramType = "query") ,
            @ApiImplicitParam(name = "startTime", value = "开始时间",
                    dataType = "string", paramType = "query") ,
            @ApiImplicitParam(name = "endTime", value = "结束时间",
                    dataType = "string", paramType = "query") ,
            @ApiImplicitParam(name="productGroupId", value = "二级产品组",
                    dataType = "int", paramType="query"),
            @ApiImplicitParam(name="refParentGroupId", value = "一级产品组",
                    dataType = "int", paramType="query")
    })
    @RequestMapping(value = "/waybillno/batch/search", method = RequestMethod.GET)
    public ResultDto queryChannelNoBatch(@RequestParam(defaultValue = "") String q ,
                                         @RequestParam(required = false, defaultValue = "true") boolean isAsc ,
                                         @RequestParam(defaultValue = "1") int pageIndex ,
                                         @RequestParam(name = "pageSize", defaultValue = "10") int pageSize ,
                                         @RequestParam(defaultValue = "") String productUid ,
                                         @RequestParam(defaultValue = "") String batchNumber ,
                                         @RequestParam(defaultValue = "") String waybillNumber ,
                                         @RequestParam(defaultValue = "") String startTime ,
                                         @RequestParam(defaultValue = "") String endTime,
                                         @RequestParam(defaultValue= "0") int productGroupId,
                                         @RequestParam(defaultValue = "0")int refParentGroupId) {
        q = StringUtils.replaceSqlPattern(q);
        Map<String,Object> paramMap = new HashMap<>();
        if (! StringUtils.isEmpty(productUid)) {
            paramMap.put("refUid" , productUid);
        }
        if (! StringUtils.isEmpty(batchNumber)) {
            paramMap.put("batchNumber" , batchNumber);
        }
        if (! StringUtils.isEmpty(waybillNumber)) {
            paramMap.put("serialNumber" , waybillNumber);
        }
        if (! StringUtils.isEmpty(startTime)) {
            paramMap.put("startTime" , startTime);
        }
        if (! StringUtils.isEmpty(endTime)) {
            paramMap.put("endTime" , endTime);
        }
        paramMap.put("type",BillNumberConstants.NumberType.WAYBILL_NUMBER);

        return noManagementService.findWaybillBatchNoByQueryParams(new QueryParams(pageSize , pageIndex , q , "" ,
                isAsc).put(paramMap),productGroupId,refParentGroupId);
    }

    @ApiOperation(value = "搜索运单号批次生成详情", notes = "搜索运单号批次")
    @ApiImplicitParams( {
            @ApiImplicitParam(name = "batchNo", value = "批次号",
                    dataType = "string", paramType = "path")
    })
    @RequestMapping(value = "/waybillno/batch/detail/{batchNo}", method = RequestMethod.GET)
    public ResultDto queryChannelNoBatchDetail(@PathVariable String batchNo) {
        NoBatchGenerateUserDto channelNoBatchGenerateUserDto = noManagementService.queryCreateUserDetail(batchNo,
                BillNumberConstants.NumberType.WAYBILL_NUMBER);
        return new ResultDto(channelNoBatchGenerateUserDto);
    }

    @ApiOperation(value = "单号搜索", notes = "单号搜索")
    @ApiImplicitParams( {
            @ApiImplicitParam(name = "q", value = "查询的关键字",
                    dataType = "string", paramType = "query") ,
            @ApiImplicitParam(name = "isAsc", value = "排序类型,true为升序，false为降序", required = false,
                    dataType = "boolean", paramType = "query") ,
            @ApiImplicitParam(name = "pageIndex", value = "分页 默认第一页",
                    dataType = "int", paramType = "query") ,
            @ApiImplicitParam(name = "pageSize", value = "页面大小",
                    dataType = "int", paramType = "query") ,
            @ApiImplicitParam(name = "orderNumber", value = "订单号",
                    dataType = "string", paramType = "query") ,
            @ApiImplicitParam(name = "batchNumber", value = "批次号",
                    dataType = "string", paramType = "query") ,
            @ApiImplicitParam(name = "waybillNumber", value = "运单号",
                    dataType = "string", paramType = "query") ,
            @ApiImplicitParam(name = "status", value = "状态, -1 全部 0 未使用 1 已使用",
                    dataType = "int", paramType = "query") ,
    })
    @RequestMapping(value = "/waybillno/search", method = RequestMethod.GET)
    public QResultDto queryWaybillNo(@RequestParam(defaultValue = "") String q ,
                                     @RequestParam(required = false, defaultValue = "true") boolean isAsc ,
                                     @RequestParam(defaultValue = "1") int pageIndex ,
                                     @RequestParam(name = "pageSize", defaultValue = "10") int pageSize ,
                                     @RequestParam(defaultValue = "") String orderNumber ,
                                     @RequestParam(defaultValue = "") String batchNumber ,
                                     @RequestParam(defaultValue = "") String waybillNumber ,
                                     @RequestParam(defaultValue = "-1") int status) {
        q = StringUtils.replaceSqlPattern(q);
        Map<String,Object> paramMap = new HashMap<>();
        if (! StringUtils.isEmpty(orderNumber)) {
            paramMap.put("orderNumber" , orderNumber);
        }
        if (! StringUtils.isEmpty(batchNumber)) {
            paramMap.put("batchNumber" , batchNumber);
        }
        if (! StringUtils.isEmpty(waybillNumber)) {
            paramMap.put("serialNumber" , waybillNumber);
        }
        if (status != - 1) {
            paramMap.put("isUsed" , status);
        }
        paramMap.put("type",BillNumberConstants.NumberType.WAYBILL_NUMBER);
        QResultDto qResultDto = noManagementService.findChannelNoByQueryParams(new QueryParams(pageSize , pageIndex , q , "" , isAsc).put
                (paramMap),2);
        return qResultDto;
    }
}
